package czh.cocoa.ui.gesture;

import czh.cocoa.foundation.NSSet;
import czh.cocoa.graphics.CGPoint;
import czh.cocoa.ui.UIEvent;
import czh.cocoa.ui.UIGestureRecognizer;
import czh.cocoa.ui.UITouch;
import czh.cocoa.ui.UIView;

public class UIPanGestureRecognizer extends UIGestureRecognizer {
	
	private final static float MIN_PAN_DIST = 10;

	private CGPoint mBeganPoint;
	
	private CGPoint mLastPoint;
	
	private CGPoint mCurrentPoint;
	
	private double mTimestamp;
	
	private double mTimeDelta;
	
	public UIPanGestureRecognizer() {
		mBeganPoint = CGPointMake(0, 0);
		mLastPoint = CGPointMake(0, 0);
		mCurrentPoint = CGPointMake(0, 0);
	}
	
	public CGPoint translationInView(UIView view) {
		CGPoint translation = CGPointMake(mCurrentPoint.x - mBeganPoint.x,
				   mCurrentPoint.y - mBeganPoint.y); 
		UIView view0 = view();
		if (view0 == view) {
			return translation;
		} else {
			return view0.convertPointToView(translation, view);
		} 
	}
	
	public CGPoint velocityInView(UIView view) {
		float vx = (float)((mCurrentPoint.x - mLastPoint.x) / mTimeDelta); 
		float vy = (float)((mCurrentPoint.y - mLastPoint.y) / mTimeDelta);
		CGPoint velocity = CGPointMake(vx, vy); 
		UIView view0 = view();
		if (view0 == view) {
			return velocity;
		} else {
			return view0.convertPointToView(velocity, view);
		}
	}
	
	public void touchesBeganWithEvent(NSSet touches, UIEvent event) {
		UITouch touch = event.firstTouch();
		mBeganPoint = touch.locationInView(view());
		mLastPoint = new CGPoint(mBeganPoint);
		mCurrentPoint = new CGPoint(mBeganPoint);
		mTimestamp = touch.timestamp();
		setState(UIGestureRecognizerStatePossible);
	}
	
	public void touchesMovedWithEvent(NSSet touches, UIEvent event) {
		UITouch touch = event.firstTouch();
		CGPoint point = touch.locationInView(view());
		
		if (!point.isEqual(mCurrentPoint)) {
			
			mLastPoint = mCurrentPoint;
			mCurrentPoint = point;
			
			double timestamp = touch.timestamp();
			mTimeDelta = timestamp - mTimestamp;
			mTimestamp = timestamp;
			
			if (state() == UIGestureRecognizerStatePossible) {
				setState(UIGestureRecognizerStateBegan); 
			} else {
				setState(UIGestureRecognizerStateChanged); 
			}
			
			
		}
		
	}
	
	public void touchesEndedWithEvent(NSSet touches, UIEvent event) {
		int state = state();
		if (state == UIGestureRecognizerStateBegan || 
				state == UIGestureRecognizerStateChanged) {
			UITouch touch = (UITouch) touches.anyObject();
			//mLastPoint = mCurrentPoint;
			mCurrentPoint = touch.locationInView(view());
			
			double timestamp = touch.timestamp();
			mTimeDelta = timestamp - mTimestamp;
			mTimestamp = timestamp;
			
			setState(UIGestureRecognizerStateEnded);
		} else {
			setState(UIGestureRecognizerStateFailed);
		}
	}
	
	public void touchesCancelledWithEvent(NSSet touches, UIEvent event) {
		if (state() == UIGestureRecognizerStatePossible) {
			setState(UIGestureRecognizerStateFailed);
		} else {
			setState(UIGestureRecognizerStateCancelled); 
		}
	}
	
}
